package com.miyake.dsp.osa.ui;

import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.HeadlessException;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableModel;

import com.miyake.dsp.common.UnitConverter;
import com.miyake.dsp.osa.AnalysisProperty;
import com.miyake.dsp.osa.NoiseFigure;
import com.miyake.dsp.osa.method.NFCalc;

public class ResultUI extends JFrame {
	private DefaultTableModel model;
	private AnalysisProperty anaProp;
	private List<Data> data = new ArrayList<Data>();
	public ResultUI() throws HeadlessException {
		super();

		initialize();
	}

	public void setAnalysisProperty(AnalysisProperty prop) {
		this.anaProp = prop;
	}
	
	private void initialize() {
		this.setTitle("Result Table");
		this.setSize(new Dimension(650, 200));
		Container c = this.getContentPane();
		c.add(createTable());
	}
	
	private Component createTable() {
		String[] titles = {"No.", "Wavelength[nm]", "Pin[dBm]", "Pout[dBm]", "Ase[dBm]", 
				"RES[nm]", "Gain[dB]", "NF[dB]", "Fit Start", "Fit End", "Mask Start", "Mask End"};
		model = new DefaultTableModel(titles, 0) {

			@Override
			public boolean isCellEditable(int arg0, int arg1) {
				if (arg1 >0 && arg1 <  7) {
					return true;
				}
				return false;
			}
			
		};
		JTable table = new JTable(model);
		model.addTableModelListener(new TableModelListener() {
			@Override
			public void tableChanged(TableModelEvent ev) {
				Data d = data.get(ev.getFirstRow());
				double k = anaProp.getK();
				double nf = 0;
				//double rbw = d.rbw;
				if (ev.getColumn() > 0 && ev.getColumn() <7) {
					double v = Double.valueOf((String)model.getValueAt(ev.getFirstRow(), ev.getColumn()));
					if (ev.getColumn() == 1) {
						d.wavelength = v;
					}
					else if (ev.getColumn() == 2) {
						d.pin = UnitConverter.toW(v);
					}
					else if (ev.getColumn() == 3) {
						d.pout = UnitConverter.toW(v);
					}
					else if (ev.getColumn() == 4) {
						d.ase = UnitConverter.toW(v);
					}
					else if (ev.getColumn() == 5) {
						d.rbw = Double.valueOf((String)model.getValueAt(ev.getFirstRow(), 5));
					}
					else if (ev.getColumn() == 6) {
						d.gain = UnitConverter.toLinear(v);
					}

					
					if (anaProp.getNfcalc().equalsIgnoreCase("Total")) {
						nf = NoiseFigure.calcNFTotal(d.ase, d.gain, d.wavelength, d.rbw, k, d.pin, 0);
					}
					else {
						nf = NoiseFigure.calcNF(d.ase, d.gain, d.wavelength, d.rbw, k);
					}
					model.setValueAt(String.format("%.5f", UnitConverter.todB(nf)),
							ev.getFirstRow(), 7);
				}
			}
		});
		return new JScrollPane(table);
	}

	public void clear() {
		model.setRowCount(0);
		data.clear();
	}
	

	
	public void addResult(double wavelength, double pin, double pout, double ase, double gain, double nf, double rbw,
			double fitStart, double fitEnd, double maskStart, double maskEnd) {
		data.add(new Data(wavelength, pin, pout, ase, gain, nf, rbw));
		
		String[] s = new String[12];
		s[0] = String.valueOf(model.getRowCount() + 1);
		s[1] = String.format("%.4f", wavelength);
		s[2] = String.format("%.3f", UnitConverter.todBm(pin));
		s[3] = String.format("%.3f", UnitConverter.todBm(pout));
		s[4] = String.format("%.3f", UnitConverter.todBm(ase));
		s[5] = String.format("%.3f", rbw);
		s[6] = String.format("%.3f", UnitConverter.todB(gain));
		s[7] = String.format("%.3f", UnitConverter.todB(nf));
		
		s[8] = String.format("%.3f", fitStart);
		s[9] = String.format("%.3f", fitEnd);
		s[10] = String.format("%.3f", maskStart);
		s[11] = String.format("%.3f", maskEnd);
		model.addRow(s);
	}
	class Data {
		public Data(double wavelength, double pin, double pout, double ase,
				double gain, double nf, double rbw) {
			super();
			this.wavelength = wavelength;
			this.pin = pin;
			this.pout = pout;
			this.ase = ase;
			this.gain = gain;
			this.nf = nf;
			this.rbw = rbw;
		}
		double wavelength;
		double pin;
		double pout;
		double ase;
		double gain;
		double nf;
		double rbw;
	}
	public void save(String filename) {
		BufferedWriter writer;
		try {
			writer = new BufferedWriter(new FileWriter(filename));
			writer.write("NO.,WAVELENGTH[nm],INPUT LVL[dBm],OUTPUT LVL[dBm],ASE LVL[dBm],RESOLN[nm],GAIN[dB],NF[dB]");
			writer.newLine();
			Integer i = 1;
			for (Data d : data) {
				writer.write(i.toString());i++;
				writer.write(",");
				writer.write(String.format("%.9f", d.wavelength));
				writer.write(",");
				writer.write(String.format("%.9f", UnitConverter.todBm(d.pin)));
				writer.write(",");
				writer.write(String.format("%.9f", UnitConverter.todBm(d.pout)));
				writer.write(",");
				writer.write(String.format("%.9f", UnitConverter.todBm(d.ase)));
				writer.write(",");
				writer.write(String.format("%.9f", d.rbw));
				writer.write(",");
				writer.write(String.format("%.9f", UnitConverter.todB(d.gain)));
				writer.write(",");
				writer.write(String.format("%.9f", UnitConverter.todB(d.nf)));
				writer.newLine();
			}
			writer.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 

	};
}
